package controller;

import handlers.SkillHandler;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import model.Observer;
import model.Subject;
import occupation.Occupation;
import skills.Skill;
import view.overlay.SkillOverlay;

public class SkillsController extends Controller implements Observer {
	
	private List<GameControl> mControls;
	
	private Occupation mOccupation;
	private SkillHandler mSkillHandler;
	
	private SkillOverlay mSkillOverlay;
	
	public SkillsController(Occupation occ, SkillHandler sh, SkillOverlay so) {
		mControls = new ArrayList<GameControl>();
		
		mSkillHandler = sh;
		
		mSkillOverlay = so;
		
		mOccupation = occ;

		updateOverlay();
		
		mSkillOverlay.setVisible(false);
	}
	
	public void showSkills() {
		mSkillOverlay.setVisible(true);
	}
	
	public void occupationChanged(Occupation occ) {
		if (mOccupation != null) {
			mOccupation.unregister(this);
		}
		mOccupation = occ;
		occ.register(this);
		updateOverlay();
	}
	
	public void setHandler(SkillHandler handler) {
		mSkillHandler = handler;
	}

	@Override
	public List<GameControl> getKeyControls() {
		mControls.clear();
		
		mControls.add(new TimedGameControl(KeyEvent.VK_1, "USE_SKILL_0", "Use Skill 1", 1000) {

			@Override
			protected void execute() {
				activateSkill(0);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_2, "USE_SKILL_1", "Use Skill 2", 1000) {

			@Override
			protected void execute() {
				activateSkill(1);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_3, "USE_SKILL_2", "Use Skill 3", 1000) {

			@Override
			protected void execute() {
				activateSkill(2);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_4, "USE_SKILL_3", "Use Skill 4", 1000) {

			@Override
			protected void execute() {
				activateSkill(3);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_5, "USE_SKILL_4", "Use Skill 5", 1000) {

			@Override
			protected void execute() {
				activateSkill(4);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_6, "USE_SKILL_5", "Use Skill 6", 1000) {

			@Override
			protected void execute() {
				activateSkill(5);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_7, "USE_SKILL_6", "Use Skill 7", 1000) {

			@Override
			protected void execute() {
				activateSkill(6);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_8, "USE_SKILL_7", "Use Skill 8", 1000) {

			@Override
			protected void execute() {
				activateSkill(7);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_9, "USE_SKILL_8", "Use Skill 9", 1000) {

			@Override
			protected void execute() {
				activateSkill(8);
				
			}
		
		});
		mControls.add(new TimedGameControl(KeyEvent.VK_0, "USE_SKILL_9", "Use Skill 10", 1000) {

			@Override
			protected void execute() {
				activateSkill(9);
				
			}
		
		});
		
		return (mControls);
	}
	
	private void activateSkill(int index) {
		mSkillHandler.useSkill(index);
		System.out.format("SkillsController::activateSkill() > Skill Activated {index=%d}\n", index);
	}
	
	private void activateSkill(Skill skill) {
		int index = mOccupation.getActiveSkillList().indexOf(skill);
		activateSkill(index);
	}
	public void deactivateSkillController() {
		for (GameControl gc : mControls) {
			gc.setEnabled(false);
		}
		mSkillOverlay.setVisible(false);
	}
	
	public void activateSkillController() {
		for (GameControl gc : mControls) {
			gc.setEnabled(true);
		}
		mSkillOverlay.setVisible(true);
	}

	@Override
	public void update(Subject sourceSubject) {
		if (sourceSubject.equals(mOccupation)) {
			// update from the occupation
			updateOverlay();
		}
		
	}
	
	private void updateOverlay() {
		Map<Skill, MouseListener> listeners = new LinkedHashMap<Skill, MouseListener>();
		
		for (final Skill s : mOccupation.getActiveSkillList()) {
			listeners.put(s, new SimpleMouseListener() {

				@Override
				public void mouseClicked(MouseEvent e) {
					// TODO Auto-generated method stub
					
					if (e.getButton() == MouseEvent.BUTTON1) {
						activateSkill(s);
					}
					else if (e.getButton() == MouseEvent.BUTTON3) {
						increaseSkill(s);
					}
					
				}
				
			});
			
		}
		
		mSkillOverlay.setSkills(listeners);
	}
	
	private void increaseSkill(Skill s) {
		int lastValue = s.getMaxRange();
		s.upgrade();
		System.out.format("MaxRange: %d -> %d\n", lastValue, s.getMaxRange());
	}
	
	@Override
	public void reset() {
		mSkillOverlay.setVisible(false);
	}

}
